diff --git a/Doc/tools/sphinxext/layout.html b/Doc/tools/sphinxext/layout.html
index d4bb105..ba76ab0 100644
--- a/Doc/tools/sphinxext/layout.html
+++ b/Doc/tools/sphinxext/layout.html
@@ -2,11 +2,20 @@
{% block rootrellink %}
- {{ shorttitle }}{{ reldelim1 }}
+ Python{{ reldelim1 }}
+
+ {% if pydoc_versionswitcher %}
+ {{ release }}
+ Documentation{{ reldelim1 }}
+ {% else %}
+ {{ shorttitle }}{{ reldelim1 }}
+ {% endif %}
+
{% endblock %}
{% block extrahead %}
{% if not embedded %}{% endif %}
+ {% if pydoc_versionswitcher %}{% endif %}
{{ super() }}
{% endblock %}
{% block footer %}
diff --git a/Doc/tools/sphinxext/pyspecific.py b/Doc/tools/sphinxext/pyspecific.py
index 814b0d3..8524d67 100644
--- a/Doc/tools/sphinxext/pyspecific.py
+++ b/Doc/tools/sphinxext/pyspecific.py
@@ -304,3 +304,8 @@ def setup(app):
app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)')
app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction)
app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod)
+
+ app.add_config_value('pydoc_versionswitcher', False, 'html')
+ def publish_plugin_config(app, pagename, templatename, context, doctree):
+ context['pydoc_versionswitcher'] = app.config.pydoc_versionswitcher
+ app.connect('html-page-context', publish_plugin_config)
diff --git a/Doc/tools/sphinxext/static/version_switch.js b/Doc/tools/sphinxext/static/version_switch.js
new file mode 100644
index 0000000..8be4078
--- /dev/null
+++ b/Doc/tools/sphinxext/static/version_switch.js
@@ -0,0 +1,110 @@
+(function() {
+ 'use strict';
+
+ var all_versions = {
+ '3.4': 'dev (3.4)',
+ '3.3': '3.3',
+ '3.2': '3.2',
+ '2.7': '2.7',
+ '2.6': '2.6'
+ };
+
+ function get_version(release) {
+ if (typeof release != 'string' || release.indexOf('.') <= 0) {
+ return;
+ }
+
+ var split = release.split('.');
+ return split[0] + '.' + split[1];
+ }
+
+ function get_doc_versions(current_release) {
+ var version = get_version(current_release),
+ doc_versions = {};
+
+ if (!version) {
+ return;
+ }
+
+ $.each(all_versions, function(version, title) {
+ doc_versions[version] = {
+ title: title
+ };
+ });
+
+ if (doc_versions.hasOwnProperty(version)) {
+ doc_versions[version].title = current_release;
+ doc_versions[version].selected = true;
+
+ return doc_versions;
+ }
+ }
+
+ function build_select(current_release) {
+ var doc_versions = get_doc_versions(current_release),
+ buf = ['');
+
+ return buf.join('');
+ }
+
+ function patch_url(url, new_version) {
+ var url_re = /\.org\/(py3k|dev|((release\/)?\d\.\d[\w\d\.]*))\//,
+ new_url = url.replace(url_re, '.org/' + new_version + '/');
+
+ if (new_url == url && !new_url.match(url_re)) {
+ // python 2 url without version?
+ new_url = url.replace(/\.org\//, '.org/' + new_version + '/');
+ }
+
+ return new_url;
+ }
+
+ function on_switch() {
+ var selected = null;
+
+ $('#version_switcher option').each(function(index, el) {
+ if (el.selected) {
+ selected = el.value;
+ }
+ });
+
+ var url = window.location.href,
+ new_url = patch_url(url, selected);
+
+ if (new_url != url) {
+ $.get(new_url, function() {
+ // url exists
+ window.location.href = new_url;
+ }).error(function() {
+ window.location.href = 'http://docs.python.org/' + selected;
+ });
+ }
+ }
+
+ $(document).ready(function() {
+ var release_version = DOCUMENTATION_OPTIONS.VERSION,
+ select = build_select(release_version);
+
+ if (select) {
+ $('#version_switcher')
+ .html(select)
+ .bind('change', on_switch);
+ }
+ });
+})();